package com.infolab.aims.web;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.infolab.aims.GlobalConstant;
import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.ParameterDateQueryHelper;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.common.exception.ResourceNotFoundException;
import com.infolab.aims.domain.Attendance;
import com.infolab.aims.domain.SystemUser;
import com.infolab.aims.service.intf.AttendanceService;
import com.infolab.aims.service.intf.SystemUserService;


@Controller
@RequestMapping("/attendance")
@SessionAttributes(value=AttendanceController.SESSION_SEARCH_CRITERIA)
public class AttendanceController extends AbstractController {

	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/attendance";
	public static final String JSP_MAIN_FORM="attendanceForm";
	public static final String JSP_MAIN_SEARCH="attendanceSearch";

	@Autowired
	AttendanceService attendanceService;

	@Autowired
	SystemUserService systemUserService;


	@RequestMapping(value="create", method = RequestMethod.GET)
	public String createAttendance(Model model) {

		model.addAttribute(new Attendance());
		return JSP_MAIN_FORM;
	}

	@RequestMapping(value="create",method=RequestMethod.POST)
	public String saveAttendance(@ModelAttribute Attendance attendance, BindingResult result,Model model,HttpServletRequest request) {


		if (validateAttendance(attendance, result)) {	
			return JSP_MAIN_FORM;
		}

		attendanceService.createAttendance(attendance);

		setSuccessMessage(getMessageResources("success.create","attendance " ));

		refreshGlobalSection(request);

		return "redirect:"+CONTEXT_PATH+"/update/" + attendance.getAttendanceId();

	}

	private boolean validateAttendance(Attendance attendance,
			BindingResult result) {
		
		SystemUser systemUser = attendance.getSystemUser();
		if(StringUtils.isNotEmpty(systemUser.getNric()))
		{
			SearchCriteria searchCriteria = new SearchCriteria();
			searchCriteria.addSearchCriteria("nric", systemUser.getNric());
			systemUser = systemUserService.findUser(searchCriteria);
			if(systemUser==null)
			{
				result.reject("error.clockInOut.noTechnician");
			}
			
			attendance.setSystemUser(systemUser);
		}
		else
			result.reject("error.clockInOut.noTechnician");
		
		
		if(!result.hasErrors())
		{
			SearchCriteria searchCriteria = new SearchCriteria();
			searchCriteria.addSearchCriteria("nric", attendance.getSystemUser().getNric());
			searchCriteria.addSearchCriteria("timeIn", new LocalDate().toDateTimeAtStartOfDay().toDate());
			Attendance curAttendance = attendanceService.findAttendance(searchCriteria);
			if(curAttendance!=null)
			{
				Long timeIn = curAttendance.getTimeIn().getTime()+(60*3*1000);
				Long timeOut = new Date().getTime();
				if(timeIn>timeOut)
					result.reject("error.attendance.clockInOut.timeProblem");
			}
		}
		
		return result.hasErrors();
	}


	@RequestMapping(value="update/{id}",method=RequestMethod.POST)
	public String updateAttendance(@PathVariable Integer id,@ModelAttribute Attendance attendance, BindingResult result,Model model,HttpServletRequest request) {

		if (validateAttendance(attendance, result)) {
			return JSP_MAIN_FORM;
		}

		attendanceService.updateAttendance(attendance);
		setSuccessMessage(getMessageResources("success.update","attendance "));

		String urlTab ="";
		if(StringUtils.isNotEmpty(request.getParameter("tab")))
		{
			urlTab = "?tab=2";
		}

		return "redirect:"+CONTEXT_PATH+"/update/" + attendance.getAttendanceId()+urlTab;	

	}

	@RequestMapping(value={"update/{id}","detail/{id}"}, method = RequestMethod.GET)
	public String detailAttendance(@PathVariable Integer id,Model model,HttpServletRequest request) {

		Attendance attendance = attendanceService.getAttendance(id);
		if(attendance==null) {
			throw new ResourceNotFoundException("Attendance " + id);
		}

		model.addAttribute(attendance);


		return JSP_MAIN_FORM;

	}


	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	}


	@ModelAttribute(AttendanceController.SESSION_SEARCH_CRITERIA)
	public SearchCriteria getAttendanceSearchCriteria()
	{
		return new SearchCriteria();
	}


	@RequestMapping(value="search")
	public String searchAttendance(@ModelAttribute(AttendanceController.SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria,@ModelAttribute("currentSearchCriteria") SearchCriteria currentSearchCriteria,Model model,HttpServletRequest request) {
	
		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());

		if(currentSearchCriteria.getSortName()==null)
		{
			searchCriteria.setSortName("attendanceId");
			searchCriteria.setSortType(SearchCriteria.SORTTYPE_DESC);
		}
		
		Date dateFrom = null;
		Date dateTo = null;
		
		try{
			if(!checkNullEmpty(searchCriteria.getSearchCriteria("timeInStart"))) {			 
				dateFrom = new SimpleDateFormat(GlobalConstant.DATE_FORMAT_JAVA).parse(searchCriteria.getSearchCriteria("timeInStart").toString());
			}
		}
		catch (ParseException e) {
			searchCriteria.addSearchCriteria("timeInStart", "");
		}
		
		try{
			
			if(!checkNullEmpty(searchCriteria.getSearchCriteria("timeInEnd"))) {			  
				dateTo= new SimpleDateFormat(GlobalConstant.DATE_FORMAT_JAVA).parse(searchCriteria.getSearchCriteria("timeInEnd").toString());
			}
		}
		catch (ParseException e) {
			searchCriteria.addSearchCriteria("timeInEnd", "");
		}

		if(!checkNullEmpty(dateFrom) &&  !checkNullEmpty(dateTo)) {
			searchCriteria.addSearchCriteria("timeIn", new ParameterDateQueryHelper("timeIn", dateFrom,dateTo));
		}
		
		else if(!checkNullEmpty(dateFrom) &&  checkNullEmpty(dateTo)){
			searchCriteria.addSearchCriteria("timeIn", new ParameterDateQueryHelper("timeIn", dateFrom, null));
		}		
		else if(checkNullEmpty(dateFrom) &&  !checkNullEmpty(dateTo)){
			searchCriteria.addSearchCriteria("timeIn", new ParameterDateQueryHelper("timeIn", null, dateTo));
		}	
		
		SearchResult searchResult = attendanceService.searchAttendance(searchCriteria);
		model.addAttribute(searchResult);

		return JSP_MAIN_SEARCH;
	}
	
	public boolean checkNullEmpty(Object obj){
		
		boolean flag=true;
		if(obj!=null && !obj.equals("")){
			flag = false;
		}
		return flag;
	
	
	}


	@RequestMapping(value="clockInOut", method = RequestMethod.GET)
	public String createClockInOut(Model model,HttpServletRequest request) {

		Attendance attendance= new Attendance();

		if(request.getSession().getAttribute("attendanceT")!=null)
		{
			attendance = (Attendance) request.getSession().getAttribute("attendanceT");
			request.getSession().removeAttribute("attendanceT");
		}

		model.addAttribute(attendance);

		return JSP_MAIN_FORM;
	}

	@RequestMapping(value="clockInOut", method = RequestMethod.POST)
	public String updateClockInOut(@ModelAttribute Attendance attendance, BindingResult result,Model model,HttpServletRequest request) {

		if (validateAttendance(attendance, result)) {
			model.addAttribute("validateFlag", "false");
			return JSP_MAIN_FORM;
		}
		//			
		attendanceService.createAttendance(attendance);

		model.addAttribute(attendance);

		if(attendance.getTimeOut()!=null)
			setSuccessMessage(getMessageResources("success.attendance.clockOut"));
		else
			setSuccessMessage(getMessageResources("success.attendance.clockIn"));

		
		request.getSession().setAttribute("attendanceT", attendance);

		return "redirect:"+CONTEXT_PATH+"/clockInOut";
	}

}
